package com.li.onjava8.concurrent.under.atomic;

import com.li.onjava8.concurrent.utils.Nap;

import java.util.concurrent.CompletableFuture;

/**
 * SerialNumberChecker 类包含一个存储最近序列号的 CircularSet 变量，以及一个填充数值给
 * CircularSet 和确保它里面的序列号是唯一的 run() 方法。
 */
public class SerialNumberChecker implements Runnable{

    private CircularSet serials = new CircularSet(1000);
    private SerialNumbers producer;

    public SerialNumberChecker(SerialNumbers producer) {
        this.producer = producer;
    }

    @Override
    public void run() {
        while (true) {
            int serial = producer.nextSerialNumber();
            if (serials.contains(serial)) {
                System.out.println("Duplicate:" + serial);
                System.exit(0);
            }
            serials.add(serial);
        }
    }

    /**
     * test() 方法创建多个任务来竞争单独的 SerialNumbers 对象。这时参于竞争的的
     * SerialNumberChecker 任务们就会试图生成重复的序列号（这情况在具有更多内核处理器的机器上发生
     * 得更快）。
     * @param producer
     */
    static void test(SerialNumbers producer) {
        for (int i = 0; i < 10; i++) {
            CompletableFuture.runAsync(new SerialNumberChecker(producer));
        }
        new Nap(4, "No duplicates detected");
    }
}
